package erfgame.core;

import java.awt.Point;
import java.awt.Rectangle;

public class Rectangle3D {
	public int minX;
	public int minY;
	public int minZ;
	public int maxX;
	public int maxY;
	public int maxZ;
	
	public Rectangle3D() {
		this( 0, 0, 0, 0, 0, 0 );
	}
	
	public Rectangle3D( Rectangle r ) {
		this( r.x, r.y, 0, r.x + r.width - 1, r.y + r.height - 1, 0 );
	}
	
	public Rectangle3D( Rectangle3D r ) {
		this( r.minX, r.minY, r.minZ, r.maxX, r.maxY, r.maxZ );
	}
	
	public Rectangle3D( int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) {
		this.maxX = maxX;
		this.maxY = maxY;
		this.maxZ = maxZ;
		this.minX = minX;
		this.minY = minY;
		this.minZ = minZ;
	}
	
	public int getX() {
		return minX;
	}

	public int getY() {
		return minY;
	}

	public int getZ() {
		return minZ;
	}

	public int getWidth() {
		return maxX - minX + 1;
	}

	public int getHeight() {
		return maxY - minY + 1;
	}

	public int getDepth() {
		return maxZ - minZ + 1;
	}
	
	@Override
	public boolean equals(Object o) {
		if( o != null && o.getClass().equals(this.getClass() ) ) {
			return equals( (Rectangle3D)o );
		} else {
			return false;
		}
	}
	
	public boolean contains( Rectangle3D r ) {
		return r.minX >= minX && r.maxX <= maxX &&
			r.minY >= minY && maxY <= maxY &&
			r.minZ >= minZ && r.maxZ <= maxZ;
	}
	
	public void merge( Rectangle3D r ) {
		this.minX = Math.min( r.minX, this.minX );
		this.minY = Math.min( r.minY, this.minY );
		this.minZ = Math.min( r.minZ, this.minZ );
		this.maxX = Math.max( r.maxX, this.maxX );
		this.maxY = Math.max( r.maxY, this.maxY );
		this.maxZ = Math.max( r.maxZ, this.maxZ );
	}
	
	public void intersect( Rectangle3D with ) {
		this.minX = Math.max( this.minX, with.minX );
		this.minY = Math.max( this.minY, with.minY );
		this.minZ = Math.max( this.minZ, with.minZ );
		this.maxX = Math.min( this.maxX, with.maxX );
		this.maxY = Math.min( this.maxY, with.maxY );
		this.maxZ = Math.min( this.maxZ, with.maxZ );
	}
	
	public boolean isEmpty() {
		return this.minX > this.maxX || this.minY > this.maxY || this.minZ > this.maxZ;
	}
	
	public boolean equals( Rectangle3D r ) {
		return r.minX == this.minX && 
			r.minY == this.minY && 
			r.minZ == this.minZ && 
			r.maxX == this.maxX && 
			r.maxY == this.maxY && 
			r.maxZ == this.maxZ;
	}
	
	public void rotate( Rotation rotation, Point around ) {
		rotate( rotation, around, new Point() );
	}
	
	public void rotate( Rotation rotation, Point aroundTimes2, Point tempPoint ) {
		rotation.rotate(minX, minY, aroundTimes2, tempPoint);
		int rMinX = tempPoint.x;
		int rMinY = tempPoint.y;
		rotation.rotate(maxX, maxY, aroundTimes2, tempPoint);
		int rMaxX = tempPoint.x;
		int rMaxY = tempPoint.y;
		minX = Math.min( rMinX, rMaxX );
		minY = Math.min( rMinY, rMaxY );
		maxX = Math.max( rMinX, rMaxX ); 
		maxY = Math.max( rMinY, rMaxY ); 
	}

	@Override
	public int hashCode() {
		return (maxX << 5)  + (minX << 4) + (maxY << 3) + (minY << 2) + (maxZ << 1) + minZ;
	}

	public String toString() {
		return "["+minX+","+minY+","+minZ+","+maxX+","+maxY+","+maxZ+"]";
	}
}
